
import { _decorator, Component, Node, Prefab, instantiate, Vec3, animation, Vec2, misc, v2, v3, Quat, quat, SkeletalAnimationComponent, Camera } from 'cc';
import { PositionMapToUIComponent } from '../common/ui/PositionMapToUIComponent';
import { PlayerData } from './PlayerData';
import { PlayerNameFlagComponent } from './PlayerNameFlagComponent';
const { ccclass, property } = _decorator;



@ccclass('PlayerComponent')
export class PlayerComponent extends Component {
    public data?: PlayerData;

    @property(SkeletalAnimationComponent)
    public aniCtl!: SkeletalAnimationComponent;

    public playerNameFlag!: PlayerNameFlagComponent;

    private preInMoving = false;
    private preInAttacking = false;

    private lastDir: Vec3 = v3();
    private targetRot: Quat = quat();
    private currRot: Quat = quat();
    private tmpRot: Quat = quat();
    private dirUseTime: number = 0;
    /**旋转过度总共应该花多少秒完成*/
    private dirAllUseTime = 0.05;

    start() {
        if (this.data) {
            this.playerNameFlag.NameText.string = this.data.showName;
            this.playerNameFlag.AppendInfo.node.active = false;
        }
    }
    update(dt: number) {
        if (this.data) {
            //这里可以插值实现平滑移动,demo简单的瞬移过去把,反正仅作显示, 数据处理帧会做好判断
            if (this.node.position.x != this.data.pos.x
                || this.node.position.z != this.data.pos.y) {
                //逻辑坐标映射成creator里的坐标,简单除30好了
                this.node.setPosition(this.data.pos.x / 30, this.node.position.y, this.data.pos.y / 30);
            }

            if (this.lastDir.x != this.data.dir.x || this.lastDir.z != this.data.dir.y) {
                this.lastDir.set(this.data.dir.x, 0, this.data.dir.y);
                //方向有变,就算出要转到的目标角度的四元数
                Quat.fromViewUp(this.targetRot, this.lastDir, Vec3.UP);
                this.dirUseTime = 0;//旋转插值重新计算
                this.currRot.set(this.node.rotation);
                if (Quat.dot(this.currRot, this.targetRot) < 0.0) {
                    //方向超过了,倒过来转会更快(如果是直接设置旋转,没差别,但插值就有中间过度了,需要取最短旋转方向)
                    this.targetRot.set(-this.targetRot.x, -this.targetRot.y, -this.targetRot.z, -this.targetRot.w);
                }
            }
            if (!this.targetRot.equals(this.node.rotation)) {
                //当前旋转方向和目标方向不一致,则需要差值转过去
                this.dirUseTime += dt;
                let t = this.dirUseTime / this.dirAllUseTime;
                if (t > 1) t = 1;
                Quat.lerp(this.tmpRot, this.currRot, this.targetRot, t);
                Quat.normalize(this.tmpRot, this.tmpRot);
                this.node.setRotation(this.tmpRot);
            }

            // 目前简单的采用状态判断播放对应动画, 准确的实现应该由逻辑层通知事件, 这里去注册对应状态变化时播放对应动画!
            if (this.preInMoving != this.data.inMoving) {
                this.preInMoving = this.data.inMoving;
                //this.aniCtl.setValue('inRunning', this.data.inMoving);
                if (this.preInMoving) {
                    this.aniCtl.play('Running');
                } else {
                    this.aniCtl.play('DwarfIdle');
                }
            }
            if (this.preInAttacking != this.data.inAttacking) {
                this.preInAttacking = this.data.inAttacking;
                //this.aniCtl.setValue('inMagicAttack', this.data.inAttacking);
                if (this.preInAttacking) {
                    this.aniCtl.play('MagicAttack01');
                } else {
                    this.aniCtl.play('DwarfIdle');
                }
            }
        }

    }

    public init(data: PlayerData, mainCamera: Camera, flagNode: Node) {
        this.data = data;
        var c = this.getComponentInChildren(PositionMapToUIComponent)!;
        c.targetUI = flagNode;
        c.camera = mainCamera;
    }
}